﻿Imports Equipment.Core
Imports Equipment.DataAccess
Imports Equipment.Business
Imports AppUser = Equipment.DataAccess.User
Imports Equipment.Model

Namespace Equipment
    <RequiresPageAcces(Page:=PageType.Users)> _
    Public Class UserController
        Inherits System.Web.Mvc.Controller

        Function Index() As ActionResult
            Dim siteList As IList(Of SiteDepartment)
            If Application.CurrentUserInfo.IsSuperUser Then
                siteList = SiteDepartment.RetrieveAll(SiteDepartmentType.Site).ToList()
            Else
                siteList = New List(Of SiteDepartment)
                siteList.Add(SiteDepartment.GetByPrimaryKey(Application.CurrentUserInfo.SiteID))
            End If
            ViewData("Site") = New SelectList(siteList, "ID", "Description")
            ViewData("Role") = New SelectList(RoleManager.GetAllFor(Application.CurrentUserInfo), "ID", "Description")
            ViewData("Users") = AppUser.RetrieveAllByStatus(UserStatus.Active)
            ViewData("EntityType") = EntityType.User
            Return View()
        End Function

#Region "AJAX"
        <HttpPost()> _
        Function CheckEmail(ByVal email As String, ByVal uid As Integer?) As ActionResult
            If Not uid.HasValue Then
                uid = 0
            End If
            Dim result As String = "Unavailable"
            Try
                Dim users = AppUser.SearchByEmailExcept(email, uid)
                If users.Count() = 0 Then
                    result = "Available"
                End If
            Catch ex As Exception

            End Try

            Return Content(result)
        End Function

        <HttpPost()> _
        Function CheckUsername(ByVal username As String, ByVal uid As Integer?) As ActionResult
            If Not uid.HasValue Then
                uid = 0
            End If
            Dim result As String = "Unavailable"
            Try
                Dim users = AppUser.SearchByUsernameExcept(username, uid)
                If users.Count() = 0 Then
                    result = "Available"
                End If
            Catch ex As Exception

            End Try

            Return Content(result)
        End Function

        <HttpPost()> _
        Function SaveUser(ByVal collection As FormCollection) As ActionResult
            Dim formSiteID As Integer = Integer.Parse(collection("UserSite"))
            Dim formId As Integer = Integer.Parse(collection("currUserID"))
            Dim formUserName As String = collection("userName")
            Dim formFirstName As String = collection("firstName")
            Dim formLastName As String = collection("lastName")
            Dim formEmail As String = collection("email")
            Dim formPassword As String = collection("password")
            Dim formConfirmPassword As String = collection("confirmPassword")
            Dim formIsUserActive As Boolean = Boolean.Parse(collection("rbUserActive"))

            Dim changeDetails As New List(Of String)


            Dim roles = Role.RetrieveAll()
            Dim groups = Group.RetrieveAll()
            Dim currUser As AppUser

            If formId > 0 Then
                currUser = AppUser.GetByPrimaryKey(formId)
            Else
                currUser = New AppUser()
            End If

            Dim existingRoleIDs = currUser.Roles.ToDictionary(Function(r) r.ID)
            Dim existingGroupIDs = currUser.Groups.ToDictionary(Function(g) g.ID)

            currUser.Roles.Clear()
            currUser.Groups.Clear()

            Dim oldFullName = currUser.FullName
            Dim oldSite = If(currUser.Site IsNot Nothing, currUser.Site.Description, String.Empty)

            For Each role As Role In roles
                Dim selectedRole As Boolean = False
                If Not String.IsNullOrEmpty(collection(String.Format("cbxRole_{0}", role.ID))) Then
                    selectedRole = Boolean.Parse(collection(String.Format("cbxRole_{0}", role.ID)).Split(",")(0))
                End If

                If selectedRole Then
                    currUser.Roles.Add(role)
                End If
                If selectedRole Then
                    If Not existingRoleIDs.ContainsKey(role.ID) Then
                        changeDetails.Add(String.Format("Added role '{0}'", role.Description))
                    End If
                Else
                    If existingRoleIDs.ContainsKey(role.ID) Then
                        changeDetails.Add(String.Format("Deleted role '{0}'", role.Description))
                    End If
                End If
            Next

            For Each group As Group In groups
                Dim selectedGroup As Boolean = False
                If Not String.IsNullOrEmpty(collection(String.Format("cbxGroup_{0}", group.ID))) Then
                    selectedGroup = Boolean.Parse(collection(String.Format("cbxGroup_{0}", group.ID)).Split(",")(0))
                End If

                If selectedGroup Then
                    currUser.Groups.Add(group)
                End If
                If selectedGroup Then
                    If Not existingGroupIDs.ContainsKey(group.ID) Then
                        changeDetails.Add(String.Format("Added group '{0}'", group.Description))
                    End If
                Else
                    If existingGroupIDs.ContainsKey(group.ID) Then
                        changeDetails.Add(String.Format("Deleted group '{0}'", group.Description))
                    End If
                End If
            Next

            If currUser.Username <> formUserName Then
                changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Username", currUser.Username, formUserName))
            End If

            If currUser.FirstName <> formFirstName Then
                changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "First Name", currUser.FirstName, formFirstName))
            End If

            If currUser.LastName <> formLastName Then
                changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Last Name", currUser.LastName, formLastName))
            End If

            If currUser.Email <> formEmail Then
                changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Email", currUser.Email, formEmail))
            End If

            If currUser.Password <> formPassword Then
                changeDetails.Add("Password was changed")
            End If

            If currUser.IsActive <> formIsUserActive Then
                If formIsUserActive Then
                    changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Status", "Inactive", "Active"))
                Else
                    changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Status", "Active", "Inactive"))
                End If
            End If

            If formId > 0 Then
                currUser.Site = currUser.DBContext.SiteDepartments.Single(Function(l) l.ID = formSiteID)
            Else
                currUser.SiteID = formSiteID
            End If
            currUser.SiteID = formSiteID
            currUser.Username = formUserName
            currUser.FirstName = formFirstName
            currUser.LastName = formLastName
            currUser.Email = formEmail
            currUser.Password = formPassword
            currUser.IsActive = formIsUserActive

            If formId > 0 Then
                currUser.Save()

                If oldSite <> currUser.Site.Description Then
                    changeDetails.Add(String.Format(Constants.UI.FIELD_MODIFICATION_TEMPLATE, "Site", oldSite, currUser.Site.Description))
                End If

                ModificationHistory.Insert(EntityType.User, currUser.FullName, ModificationAction.Modified, Application.CurrentUserInfo.UserID, changeDetails, currUser.ID, currUser.SiteID)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.User_Modify, oldFullName, currUser)
            Else
                AppUser.Insert(currUser)
                changeDetails = New List(Of String)
                changeDetails.Add(String.Format(Constants.UI.FIELD_SET_TEMPLATE, "Username", currUser.Username))
                changeDetails.Add(String.Format(Constants.UI.FIELD_SET_TEMPLATE, "Full Name", currUser.FullName))
                changeDetails.Add(String.Format(Constants.UI.FIELD_SET_TEMPLATE, "Email", currUser.Email))
                ModificationHistory.Insert(EntityType.User, currUser.FullName, ModificationAction.Created, Application.CurrentUserInfo.UserID, changeDetails, currUser.ID, currUser.SiteID)
                NotificationManager.CreateNotificationsByTrigger(NotificationTrigger.User_Create, currUser.FullName, currUser)
            End If

            ViewData("Users") = AppUser.RetrieveAll()
            Return PartialView("~/Views/User/Controls/UserGrid.ascx")
        End Function

        Function UserDetail(ByVal id As Integer) As ActionResult
            Dim currUser As AppUser
            Dim siteList As IList(Of SiteDepartment)
            Dim selectedSiteID As Integer = 0

            If Application.CurrentUserInfo.IsSuperUser Then
                siteList = SiteDepartment.RetrieveAll(SiteDepartmentType.Site).ToList()
            Else
                siteList = New List(Of SiteDepartment)
                siteList.Add(SiteDepartment.GetByPrimaryKey(Application.CurrentUserInfo.SiteID))
            End If

            If id > 0 Then
                currUser = AppUser.GetByPrimaryKey(id)
                ViewData("UserSite") = New SelectList(siteList, "ID", "Description", currUser.SiteID)
                selectedSiteID = currUser.SiteID
            Else
                currUser = New AppUser() With {.ID = 0, .SiteID = 0}
                ViewData("UserSite") = New SelectList(siteList, "ID", "Description")
                If Application.CurrentUserInfo.IsSuperUser Then
                    selectedSiteID = siteList.First().ID
                Else
                    selectedSiteID = Application.CurrentUserInfo.SiteID
                End If
            End If

            ViewData("CurrentUser") = currUser
            ViewData("Roles") = Role.RetrieveAllBySiteID(selectedSiteID)
            ViewData("Groups") = Group.RetrieveAllBySiteID(selectedSiteID)

            For Each selectedRole In currUser.Roles
                ViewData(String.Format("SelectedRole_{0}", selectedRole.ID)) = True
            Next

            For Each selectedGroup In currUser.Groups
                ViewData(String.Format("SelectedGroup_{0}", selectedGroup.ID)) = True
            Next

            Return PartialView("~/Views/User/Controls/UserDetail.ascx")
        End Function

        <HttpPost()> _
        Function GetAvailableRoles(ByVal siteID As Integer) As ActionResult

            ViewData("Roles") = Role.RetrieveAllBySiteID(siteID)

            Return PartialView("~/Views/User/Controls/RoleSelectionGrid.ascx")
        End Function

        <HttpPost()> _
        Function GetAvailableGroups(ByVal siteID As Integer) As ActionResult

            ViewData("Groups") = Group.RetrieveAllBySiteID(siteID)

            Return PartialView("~/Views/User/Controls/GroupSelectionGrid.ascx")
        End Function


        <HttpPost()> _
        Function FilterUsers(ByVal siteID As Integer?, ByVal roleID As Integer?, ByVal status As String) As ActionResult
            If Not siteID.HasValue Then
                siteID = 0
            End If
            If Not roleID.HasValue Then
                roleID = 0
            End If

            Dim users As IEnumerable(Of User)
            If String.IsNullOrEmpty(status) Then
                users = AppUser.RetrieveAll(siteID.Value, roleID.Value)
            Else
                users = AppUser.RetrieveAll(siteID, roleID, DirectCast([Enum].Parse(GetType(UserStatus), status), UserStatus))
            End If

            ViewData("Users") = users

            Return PartialView("~/Views/User/Controls/UserGrid.ascx")
        End Function
#End Region

    End Class
End Namespace